'use strict'

const Controller = require('egg').Controller

/**
 * @controller User 用户模块
 */

class UserController extends Controller {

  // 内部调用，获取当前登录用户信息
  async getCurrentInfo() {
    const { service, helper, request } = this.ctx

    let token = null
    if (request.headers.authorization && request.headers.authorization.split(' ')[0] === 'Bearer') {
      token = request.headers.authorization.split(' ')[1]
      if (token) {
        const decode = this.app.jwt.verify(token, this.app.config.jwt.secret)
        if (decode && decode?.id) {
          const data = await service.user.info(decode.id)
          if (data) {
            return data
          }
        }
      }
    }
    return null
  }

  /**
   * @summary 小程序登录
   * @description 目前仅支持微信小程序登录
   * @router post /v1/user/wx_login
   * @request body RequestWXLogin
   * @response 0 UserInfo
   */
  async wx_login() {
    const { service, helper, session, request, validate, rotateCsrfSecret, rule } = this.ctx
    // const { code, nickName, avatarUrl, phone, gender, province, city, language } = request.body
    const { code } = request.body
    console.log('微信登录', request.body)
    // 参数校验
    const passed = await validate.call(this, rule.RequestWXLogin, request.body)
    if (!passed) {
      helper.error(null, '参数错误')
      return
    }

    // 微信登录凭证校验，通过 code 换取用户信息，包含 openId 和 unionId
    const token = await service.wechatApp.code2Session(code)
    if (!token) {
      helper.error(null, '微信登录鉴权失败')
      return
    }

    const { open_id, union_id } = token
    const data = await service.user.wx_login({
      open_id,
      union_id
    })
    if (data) {
      // 返回用户信息
      session.user_id = data.id
      session.open_id = data.open_id
      session.nickName = data.nickName
      rotateCsrfSecret.call(this)
      delete data.password
      data.token = helper.GenerateToken({ phone: data.phone, open_id: data.open_id })
      helper.success(data, '微信登录成功')
    }
  }

  /**
   * @summary 获取手机号并注册新用户
   * @description 获取用户当前绑定的手机号码
   * @router post /v1/user/wx_phone
   * @request body RequestPhone
   * @response 0 UserInfo
   */
  async wx_phone() {
    const { service, helper, session, request, validate, rule } = this.ctx
    const { code, open_id } = request.body

    // 参数校验（复用 egg-swagger-doc 结构来校验）
    const passed = await validate.call(this, rule.RequestPhone, request.body)
    if (!passed) {
      helper.error(null, '参数错误')
      return
    }

    const token = await service.wechatApp.accessToken()
    const phoneData = await service.wechatApp.getPhoneNumber(token.accessToken, code)
    if (phoneData) {
      const data = await service.user.createUser({
        phone: phoneData.phoneNumber,
        open_id
      })
      if (data) {
        data.token = helper.GenerateToken({ phone: phoneData.phoneNumber, open_id })
        helper.success(data)
      }
    } else {
      helper.error(null, '手机号授权异常')
    }
  }

  /**
   * @summary 分页查询用户列表
   * @description 分页查询用户列表
   * @router post /v1/user/list
   * @request body UserList params 分页参数
   * @response 0 UserInfo
   */
  async list() {
    const { service, helper, request } = this.ctx
    const params = request.body

    const data = await service.user.getUserList(params)
    if (data) {
      helper.success(data)
    }
  }

  /**
   * @summary 新建用户
   * @description 新建用户
   * @router post /v1/user/create
   * @request body UserCreate
   * @response 0 UserInfo
   */
  async create() {
    const { service, helper, session, request, validate, rule } = this.ctx

    // 参数校验（复用 egg-swagger-doc 结构来校验）
    const passed = await validate.call(this, rule.UserCreate, request.body)
    if (!passed) {
      helper.error(null, '参数错误')
      return
    }

    const params = request.body
    params.phone = params.account
    const data = await service.user.createUser(params)
    if (data) {
      helper.success(data)
    }
  }

  /**
   * @summary 修改个人密码
   * @description 修改个人密码
   * @router post /v1/user/changepwd
   * @request body UserEditPwd
   * @response 0 UserInfo
   */
  async change_password() {
    const { service, helper, session, request, validate, rule } = this.ctx

    // 参数校验（复用 egg-swagger-doc 结构来校验）
    const passed = await validate.call(this, rule.UserEditPwd, request.body)
    if (!passed) {
      helper.error(null, '参数错误')
      return
    }

    const curUser = await this.getCurrentInfo()
    if (!curUser) {
      helper.error(null, '未登录')
      return
    }
    if (curUser.id !== request.body.id) {
      helper.error(null, '无权限')
      return
    }

    const data = await service.user.changePassword(request.body)
    if (data) {
      helper.success(data)
    }
  }

  /**
   * @summary 编辑用户信息
   * @description 编辑用户信息
   * @router post /v1/user/edit
   * @request body UserEdit params 用户ID
   * @response 0 UserInfo
   */
  async edit() {
    const { service, helper, session, request, validate, rule } = this.ctx

    // 参数校验（复用 egg-swagger-doc 结构来校验）
    const passed = await validate.call(this, rule.UserEdit, request.body)
    if (!passed) {
      helper.error(null, '参数错误')
      return
    }

    const data = await service.user.editUser(request.body)
    if (data) {
      helper.success(data)
    }
  }

  /**
   * @summary 删除用户
   * @description 删除用户信息
   * @router post /v1/user/delete
   * @request body UserDelete params 用户ID
   * @response 0 UserInfo
   */
  async delete() {
    const { service, helper, session, request, validate, rule } = this.ctx

    // 参数校验（复用 egg-swagger-doc 结构来校验）
    const passed = await validate.call(this, rule.UserDelete, request.body)
    if (!passed) {
      helper.error(null, '参数错误')
      return
    }

    const data = await service.user.deleteUser(request.body)
    if (data) {
      helper.success(data)
    }
  }


  /**
   * @summary 小程序登出
   * @description 小程序退出登录
   * @router post /v1/user/wx_logout
   * @response 0
   */
  async wx_logout() {
    const { helper, session } = this.ctx
    session.userId = null
    session.openId = null
    session.nickName = null
    helper.success()
  }

  /**
   * @summary 登录
   * @description 账号密码登录
   * @router post /v1/user/login
   * @request body UserLogin params 登录参数（密码 MD5加密）
   * @response 0
   */
  async login() {
    const { ctx, app } = this
    const { service, helper, logger, session, request, validate, rotateCsrfSecret, rule } = ctx
    const { account, password } = request.body

    // 参数校验
    const passed = await validate.call(this, rule.RequestLoginByPassword, request.body)
    if (!passed) {
      logger.warn('登录参数错误 %s', request.body)
      helper.error(null, '参数错误')
      return
    }
    const params = {
      phone: account,
      password
    }
    const data = await service.user.login(params)
    if (data) {
      delete data.unionId
      delete data.password
      params.id = data.id
      data.token = helper.GenerateToken(params)
      helper.addToken(data.id, data.token)
      helper.success(data, '登录成功')
    }
  }

  /**
   * @summary 登出
   * @description 退出登录
   * @router post /v1/user/logout
   * @response 0
   */
  async logout() {
    const { request, helper, session } = this.ctx
    const { userid } = request.body
    session.userId = null
    session.openId = null
    session.nickName = null
    helper.subToken(userid)
    helper.success(null, '注销成功')
  }


}

module.exports = UserController
